#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../../Include/domain/database_info.h"
#include "../../Include/domain/bp_info.h"
#include "../../Include/constant/filename.h"
#include "../../Include/util/config_util.h"
#include "../../Include/manager/log_manager.h"

/**
 * 字符数组的长度
 */
int CONFIG_HANDLER_ARRAY_LENGTH = 128;

/**
 * 从配置文件中获取数据库的配置
 * @return
 */
struct DatabaseInfo *GetDatabaseInfo() {
    struct DatabaseInfo *databaseInfo = (struct DatabaseInfo *)malloc(sizeof(struct DatabaseInfo));
	// 从配置文件中获取用户名、密码、数据库名、数据库连接字符串
	char *absolutePath = MakeAbsolutePath(CONFIG_FILENAME);
	void *handle;
	int result = init(absolutePath, &handle);

	char *usernameKey = "database.username";
	char *usernameValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));
	char *passwordKey = "database.password";
	char *passwordValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));
	char *schemaKey = "database.schema";
	char *schemaValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));
	char *urlKey = "database.url";
	char *urlValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));

	result = getValue(handle, usernameKey, usernameValue);
	result = getValue(handle, passwordKey, passwordValue);
	result = getValue(handle, schemaKey, schemaValue);
	result = getValue(handle, urlKey, urlValue);

	databaseInfo->username = usernameValue;
	databaseInfo->password = passwordValue;
	databaseInfo->schema = schemaValue;
	databaseInfo->url = urlValue;

	return databaseInfo;
}

/**
 * 从配置文件中获取反向传播网络算法的配置
 * @return
 */
struct BPInfo *GetBPInfo() {
    struct BPInfo *bpInfo = (struct BPInfo *)malloc(sizeof(struct BPInfo));
	// 从配置文件中获取w1的行数、w1的列数、w2的行数、w2的列数
	char *absolutePath = MakeAbsolutePath(CONFIG_FILENAME);
	void *handle;
	int result = init(absolutePath, &handle);

	char *w1RowNumberKey = "BP.w1.row.number";
	char *w1RowNumberValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));
	char *w1ColumnNumberKey = "BP.w1.column.number";
	char *w1ColumnNumberValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));
	char *w2RowNumberKey = "BP.w2.row.number";
	char *w2RowNumberValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));
	char *w2ColumnNumberKey = "BP.w2.column.number";
	char *w2ColumnNumberValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));
	char *arrayRandomLimitKey = "BP.array.random.limit";
	char *arrayRandomLimitValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));
    char *initLearningRateKey = "BP.init.learning.rate";
    char *initLearningRateValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));
    char *decayRateKey = "BP.decay.rate";
    char *decayRateValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));
    char *decayStepsKey = "BP.decay.steps";
    char *decayStepsValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));
    char *lossValueKey = "BP.loss.value";
    char *lossValueValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));
    char *l2RegularizationRateKey = "BP.l2.regularization.rate";
    char *l2RegularizationRateValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));
    char *trainDataSetBeginDateKey = "train.data.set.begin.date";
    char *trainDataSetBeginDateValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));
    char *trainDataSetEndDateKey = "train.data.set.end.date";
    char *trainDataSetEndDateValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));
    char *testDataSetBeginDateKey = "test.data.set.begin.date";
    char *testDataSetBeginDateValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));
    char *testDataSetEndDateKey = "test.data.set.end.date";
    char *testDataSetEndDateValue = (char *)malloc(CONFIG_HANDLER_ARRAY_LENGTH * sizeof(char));

	result = getValue(handle, w1RowNumberKey, w1RowNumberValue);
	result = getValue(handle, w1ColumnNumberKey, w1ColumnNumberValue);
	result = getValue(handle, w2RowNumberKey, w2RowNumberValue);
	result = getValue(handle, w2ColumnNumberKey, w2ColumnNumberValue);
	result = getValue(handle, arrayRandomLimitKey, arrayRandomLimitValue);
    result = getValue(handle, initLearningRateKey, initLearningRateValue);
    result = getValue(handle, decayRateKey, decayRateValue);
    result = getValue(handle, decayStepsKey, decayStepsValue);
    result = getValue(handle, lossValueKey, lossValueValue);
    result = getValue(handle, l2RegularizationRateKey, l2RegularizationRateValue);
    result = getValue(handle, trainDataSetBeginDateKey, trainDataSetBeginDateValue);
    result = getValue(handle, trainDataSetEndDateKey, trainDataSetEndDateValue);
    result = getValue(handle, testDataSetBeginDateKey, testDataSetBeginDateValue);
    result = getValue(handle, testDataSetEndDateKey, testDataSetEndDateValue);

	bpInfo->w1RowNumber = atoi(w1RowNumberValue);
	bpInfo->w1ColumnNumber = atoi(w1ColumnNumberValue);
	bpInfo->w2RowNumber = atoi(w2RowNumberValue);
	bpInfo->w2ColumnNumber = atoi(w2ColumnNumberValue);
	bpInfo->arrayRandomLimit = atof(arrayRandomLimitValue);
    bpInfo->initLearningRate = atof(initLearningRateValue);
    bpInfo->decayRate = atof(decayRateValue);
    bpInfo->decaySteps = atof(decayStepsValue);
    bpInfo->lossValue = atof(lossValueValue);
    bpInfo->l2RegularizationRate = atof(l2RegularizationRateValue);
    bpInfo->trainDataSetBeginDate = trainDataSetBeginDateValue;
    bpInfo->trainDataSetEndDate = trainDataSetEndDateValue;
    bpInfo->testDataSetBeginDate = testDataSetBeginDateValue;
    bpInfo->testDataSetEndDate = testDataSetEndDateValue;

    return bpInfo;
}
